CFSSL = "cfssl"
CFSSL_JSON = "cfssl-json"
KUBECTL = "kubectl"


# ca、cert------------------------------------------------------------------------

def cmd_gen_ca_cert(csr_config: str, cert_dir=".", cert_name="ca"):
    """
    生成自签的ca证书以及对应的私钥、公钥
    :param ca_csr_conf: ca-csr.json

    :return:
        xxx.pem          证书，包含公钥
        xxx-key.pem      私钥
        xxx.csr          csr文件
    """
    chains = []
    chains.append(
        "{CFSSL} gencert -initca {csr_config}".format(
            CFSSL=CFSSL,
            csr_config=csr_config,
        )
    )
    chains.append(
        "{CFSSL_JSON} -bare {cert_dir}/{cert_name}".format(
            CFSSL_JSON=CFSSL_JSON,
            cert_dir=cert_dir,
            cert_name=cert_name,
        )
    )

    return chains


def cmd_gen_key_cert(ca_public, ca_private, ca_config, profile, csr_config, cert_name, cert_dir="."):
    """
    通过自签ca证书生成服务证书以及对应的私钥、公钥
    :param ca_public: ca公钥
    :param ca_private: ca私钥
    :param ca_config: ca配置文件，通常为ca-config.json
    :param profile: ca配置文件中的不同证书配置项，指定使用 该参数值 配置文件中定义的签名策略和参数
    :param csr_config: 自签服务的证书生成配置
    :param cert_name: 自签服务名称，即生成的证书名称

    :return:
        xxx.pem          公钥
        xxx-key.pem      私钥
        xxx.csr          csr文件

    """
    chains = []
    chains.append(
        "{CFSSL} gencert -ca={ca_public} -ca-key={ca_private} -config={ca_config} -profile={profile} {csr_config} ".format(
            CFSSL=CFSSL,
            ca_public=ca_public,
            ca_private=ca_private,
            ca_config=ca_config,
            profile=profile,
            csr_config=csr_config,
        )
    )
    chains.append(
        "{CFSSL_JSON} -bare {cert_dir}/{cert_name}".format(
            CFSSL_JSON=CFSSL_JSON,
            cert_dir=cert_dir,
            cert_name=cert_name,
        )
    )

    return chains


def cmd_get_cert_info(cert_file):
    """
    :param cert_file: 公钥文件路径
    :return:
    """
    chains = []
    chains.append(
        "{CFSSL} certinfo -cert {cert_file}".format(
            CFSSL=CFSSL,
            cert_file=cert_file
        )
    )
    return chains


# kube config------------------------------------------------------------------------

def _set_cluster(cluster, ca_path, apiserver_host, kube_config_path):
    # 配置集群参数
    cmd = "kubectl config set-cluster {cluster} " \
          "--certificate-authority={ca_path} " \
          "--embed-certs=true " \
          "--server={apiserver_host} " \
          "--kubeconfig={kube_config_path}".format(
        cluster=cluster,
        ca_path=ca_path,
        apiserver_host=apiserver_host,
        kube_config_path=kube_config_path
    )
    return cmd


def _set_credentials(user, public_key, private_key, conf_file):
    # 通过cert配置客户端认证参数
    cmd = "kubectl config set-credentials {} " \
          "--client-certificate={} " \
          "--client-key={} " \
          "--embed-certs=true " \
          "--kubeconfig={}".format(user, public_key, private_key, conf_file)
    return cmd


def _set_credentials_by_token(user, token, conf_file):
    # 通过token配置客户端认证参数
    cmd = "kubectl config set-credentials {} " \
          "--token={} " \
          "--kubeconfig={}".format(user, token, conf_file)
    return cmd


def _set_context(cluster, context, user, conf_file):
    # 设置context
    cmd = "kubectl config set-context {} " \
          "--cluster={} " \
          "--user={} " \
          "--kubeconfig={}".format(context, cluster, user, conf_file)
    return cmd


def _set_default_context(context, conf_file):
    # 设置默认context
    cmd = "kubectl config use-context {} --kubeconfig={}".format(context, conf_file)
    return cmd


def cmd_gen_kube_config(by, cluster, apiserver, conf, user, context, ca, cert="", cert_key="", token=""):
    """
    :param by: 生成方式；cert代表通过证书生成；token代表通过apiserver的token生成(主要用于生成kubelet启动的bootstrap—kubeconfig)
    :param cluster: 集群名称
    :param apiserver: 集群apiserver访问地址；https://172.0.0.1:6443
    :param conf: 生成的kubeconfig文件路径
    :param user: 用户名
    :param context: 上下文
    :param ca: ca证书路径
    :param cert: cert证书路径
    :param cert_key: cert私钥路径
    :param token: apiserver中配置的token
    :return:
    """
    chains = []
    chains.append(_set_cluster(cluster, ca, apiserver, conf))
    if by == "cert":
        chains.append(_set_credentials(user, cert, cert_key, conf))
    elif by == "token":
        chains.append(_set_credentials_by_token(user, token, conf))

    chains.append(_set_context(cluster, context, user, conf))

    return chains


def cmd_set_default_context(conf, default_context):
    chains = [
        _set_default_context(default_context, conf)
    ]

    return chains
